package com.myproject.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import com.myproject.dto.*;
import com.myproject.entity.User;
import com.myproject.exception.BusinessException;
import com.myproject.service.UserService;
import com.myproject.vo.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 用户管理控制器
 * 
 * <p>
 * 提供用户相关的RESTful API接口，包括：
 * </p>
 * <ul>
 * <li>用户注册</li>
 * <li>用户登录</li>
 * <li>用户信息管理</li>
 * <li>密码修改</li>
 * </ul>
 * 
 * <p>
 * 所有API路径前缀为/user，返回结果统一包装为Result对象
 * </p>
 * 
 * <p>
 * 使用注解：
 * 
 * @RestController - 标记为REST控制器
 * @RequestMapping - 定义基础路径
 * @Tag - Swagger文档分组
 *      </p>
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户注册、登录及信息管理接口")
public class UserController {

	/**
	 * 用户服务，提供用户相关的业务逻辑
	 */
	@Autowired
	private UserService userService;

	/**
	 * 用户注册接口（API版本）
	 * 
	 * @param user 用户实体对象，包含用户名和密码
	 * @return 空结果，表示注册成功
	 */
	@PostMapping("/api/register")
	@Operation(summary = "用户注册", description = "新用户账号注册")
	public Result<Void> apiRegister(@RequestBody User user) {
		userService.register(user);
		return Result.success();
	}

	/**
	 * 用户登录接口（API版本）
	 * 
	 * @param user 用户实体对象，包含用户名和密码
	 * @return 包含JWT令牌的结果
	 */
	@PostMapping("/api/login")
	@Operation(summary = "用户登录", description = "用户账号登录并获取Token")
	public Result<String> apiLogin(@RequestBody User user) {
		String token = userService.login(user.getUsername(), user.getPassword());
		return Result.success(token);
	}

	/**
	 * 用户注册接口（完整版）
	 * 
	 * @param userDTO 用户注册数据传输对象
	 * @return 空结果，表示注册成功
	 * @throws BusinessException 如果用户名已存在或其他业务规则验证失败
	 */
	@PostMapping("/register")
	@Operation(summary = "用户注册", description = "新用户账号注册")
	public Result<Void> register(@Valid @RequestBody UserRegisterDTO userDTO) throws BusinessException {
		User user = new User();
		user.setUsername(userDTO.getUsername());
		user.setPassword(userDTO.getPassword());
		user.setNickname(userDTO.getNickname());
		user.setEmail(userDTO.getEmail());
		userService.register(user);
		return Result.success();
	}

	/**
	 * 用户登录接口（完整版）
	 * 
	 * @param userDTO 用户登录数据传输对象
	 * @return 包含JWT令牌的结果
	 * @throws BusinessException 如果用户名或密码错误
	 */
	@PostMapping("/login")
	@Operation(summary = "用户登录", description = "用户账号登录并获取Token")
	public Result<String> login(@Valid @RequestBody UserLoginDTO userDTO) throws BusinessException {
		String token = userService.login(userDTO.getUsername(), userDTO.getPassword());
		return Result.success(token);
	}

	/**
	 * 获取用户信息
	 * 
	 * @param userId 用户ID
	 * @return 包含用户信息的结果
	 */
	@GetMapping("/info/{userId}")
	@Operation(summary = "获取用户信息")
	public Result<User> getUserInfo(@Parameter(description = "用户ID", required = true) @PathVariable Long userId) {
		User user = userService.getUserById(userId);
		return Result.success(user);
	}

	/**
	 * 更新用户信息
	 * 
	 * @param user 用户实体对象，包含要更新的信息
	 * @return 空结果，表示更新成功
	 * @throws BusinessException 如果用户不存在或更新失败
	 */
	@PutMapping("/update")
	@Operation(summary = "更新用户信息", description = "更新用户昵称、邮箱等非敏感信息")
	public Result<Void> updateUser(@RequestBody User user) throws BusinessException {
		userService.updateUser(user);
		return Result.success();
	}

	/**
	 * 修改用户密码
	 * 
	 * @param userId      用户ID
	 * @param oldPassword 旧密码
	 * @param newPassword 新密码
	 * @return 空结果，表示密码修改成功
	 * @throws BusinessException 如果旧密码验证失败或用户不存在
	 */
	@PostMapping("/changePassword")
	@Operation(summary = "修改密码", description = "需验证旧密码")
	public Result<Void> changePassword(@Parameter(description = "用户ID", required = true) @RequestParam Long userId,
			@Parameter(description = "旧密码", required = true) @RequestParam String oldPassword,
			@Parameter(description = "新密码", required = true) @RequestParam String newPassword)
			throws BusinessException {
		userService.changePassword(userId, oldPassword, newPassword);
		return Result.success();
	}

	/**
	 * 获取用户列表（分页）
	 * 
	 * @param page 页码，从0开始
	 * @param size 每页大小
	 * @return 包含分页用户列表的结果
	 */
	@GetMapping("/list")
	@Operation(summary = "获取用户列表", description = "分页查询用户列表")
	public Result<Page<User>> getUserList(
			@Parameter(description = "页码，从0开始", example = "0") @RequestParam(defaultValue = "0") int page,
			@Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") int size) {
		Page<User> userPage = userService.getUserList(page, size);
		return Result.success(userPage);
	}
}